# ext仿vue mixin效果
最近在做ext项目时,发现给页面加同一功能时总是需要复制粘贴同一份代码,ext自带的只有继承,用继承来实现挺麻烦的,所以想到了用vue中的mixin来实现需求。
# 实现
参考了页面结构后,总结出几种类型:
- 生命周期(函数形式)
- actions(对象形式,需递归合并)
- 其他(直接合并)
那么来动手实现吧
源代码如下:
/**
* 仿Vue mixin 做混入操作
* 有冲突的以main为主
* @param main
* @param second
*/
SF.mixin = function (main, second) {
for (var key in second) {
if (second.hasOwnProperty(key)) {
if (key === 'onInit' || key === 'initMgr') {
// merge function
if (main.hasOwnProperty(key)) {
// 为了兼容单独mgr的写法,有才去合并
main[key] = mergeFunction(main[key], second[key]);
}
} else if (key === 'actions') {
// merge object
SF.mixin(main[key], second[key]);
} else {
// cover
if (!main.hasOwnProperty(key)) {
main[key] = second[key];
}
}
}
}
};
/**
* 合并两个函数,不做替换,依次执行
* @param mainFunction
* @param secondFunction
* @returns {function(...[*]=)}
*/
var mergeFunction = function (mainFunction, secondFunction) {
return function () {
mainFunction.call(this);
secondFunction.call(this);
};
};
因为所涉及的页面比较少,所以实现上也是很简单。
函数形式的就返回个新函数,其中调用需合并的函数,注意需要改变this指向。
actions就需要将两个对象合并在一起,这里直接递归调用,再走普通形式即可。
普通数据的话,如果主合并对象存在该属性,则以主的为准,不存在时再将被复制对象复制给主对象。
# 使用
下面来看下怎么用吧
将公共部分的代码写在一个对象中,再按常规操作导出
var moveNumberPlugin = {
onInit: xxx,
actions: xxx
}
Ext.ns('B.commonUtils');
B.commonUtils.moveNumberPlugin = moveNumberPlugin;
在需要的页面调用
SF.mixin(main, moveNumberPlugin)
即可完成合并
因为是直接对对象操作,所以不需要再赋值给主对象
# 不足
这里需要SF.mixin()
一下,跟vue中写法还是不一样的。
原因主要是按照vue的写法的话,需要改动ext的源码,考虑到需要耗费的时间,还是直接用这种方式简单些。